#include "CParticleEmitter.h"
#include "../tinyxml/tinyxml.h"
#include <fstream>
#include <ctime>


CParticleEmitter::CParticleEmitter()
{
	name = "new";
	particleRate = 10;
	imageId = -1;
	name = "";
	lifeTime = 0.0f;
	timer = 1.0f/particleRate;
	burstTimer = 0.0f;
	originalBurstTime = 0.0f;
	waitTimer = 0.0f;
	numberOfParticles = 0;

	startPosX = 0.0f;
	startPosY = 0.0f;
	startVelX = 0.0f;
	startVelY = 0.0f;
	startScale = 0.0f;

	ratePosX = 0.0f;
	ratePosY = 0.0f;
	rateVelX = 0.0f;
	rateVelY = 0.0f;
	rateScale = 0.0f;

	randomVelocity.fX = 0.0f;
	randomVelocity.fY = 0.0f;
	randomAngle = 0.0f;

	emitterRectWidth = 0;
	emitterRectHeight = 0;

	sourceBlend = 0;
	destinationBlend = 0;

	isLooping = true;
	active = true;
	titleState = false;
}

CParticleEmitter::~CParticleEmitter()
{
}

void CParticleEmitter::Update(float gameTime)
{
	timer -= gameTime;

	if(deadParticles.size() > 0 && aliveParticles.size() < (unsigned int)numberOfParticles && active == true)
	{
		int xOffset = rand()%emitterRectWidth - (emitterRectWidth>>1);
		int yOffset = rand()%emitterRectHeight - (emitterRectHeight>>1);

		if(!isLooping)
		{
			burstTimer -= gameTime;

			if(burstTimer > 0)
			{
				for(int i = 0; i < numberOfParticles; ++i)
				{
					if(timer <= 0)// || !isLooping)
					{
						float randomVelX = (float)(rand()%5-3);
						float randomVelY = (float)(rand()%5-5);

						randomAngle = (float)(rand()%90-45);
						randomAngle = (randomAngle/180)*SGD_PI;

						randomVelocity = Vector2DRotate(randomVelocity,randomAngle);

						Particle* add = new Particle(startPosX + xOffset,startPosY + yOffset,randomVelocity.fX,randomVelocity.fY,startScale,startColor,lifeTime);
						aliveParticles.push_back(add);
						timer = 1.0f/particleRate;
					}
				}
			}
		}
		else
		{
			if(timer <= 0)
			{
				burstTimer -= gameTime;
				Particle* add = new Particle(startPosX + xOffset,startPosY + yOffset,startVelX,startVelY,startScale,startColor,lifeTime);
				aliveParticles.push_back(add);
				timer = 1.0f/particleRate;
			}
		}
	}

	for (unsigned i = 0; i < aliveParticles.size(); ++i)
	{
		if(burstTimer == burstTimer*0.5f)
		{
			ratePosX = -1.0f*ratePosX;
			rateVelX = -1.0f*rateVelX;
		}

		if(!isLooping)
		{
			aliveParticles[i]->SetPosX(aliveParticles[i]->GetPosX() + ratePosX);
			aliveParticles[i]->SetPosY(aliveParticles[i]->GetPosY() + ratePosY);
			aliveParticles[i]->SetScale(aliveParticles[i]->GetScale() + rateScale);
		}
		else
		{
			aliveParticles[i]->SetPosX(aliveParticles[i]->GetPosX() + ratePosX);
			aliveParticles[i]->SetPosY(aliveParticles[i]->GetPosY() + ratePosY);
			aliveParticles[i]->SetVelX(aliveParticles[i]->GetVelX() + rateVelX);
			aliveParticles[i]->SetVelY(aliveParticles[i]->GetVelY() + rateVelY);
			aliveParticles[i]->SetScale(aliveParticles[i]->GetScale() + rateScale);
		}

		//int tempColor[4];
		//for(int k = 0; k < 4; ++k)
		//{
		//	tempColor[0] = (int)startColorData[0] + (int)rateColor[0];
		//}

		//for (int j = 0; j < 4; j++)
		//{
		//	if (tempColor[j] > 255)
		//		tempColor[j] = 255;
		//	else if (tempColor[j] < 0)
		//		tempColor[j] = 0;
		//}

		//aliveParticles[i]->color = D3DCOLOR_ARGB(tempColor[0], tempColor[1], tempColor[2], tempColor[3]);

		aliveParticles[i]->Update(gameTime);

		if(aliveParticles[i]->GetLifeTime() <= 0)
		{
			Particle* add = aliveParticles[i];
			aliveParticles.erase(aliveParticles.begin()+i);
			deadParticles.push_back(add);
		}

		//if(burstTimer <= 0)
		//{
		//	delete this;
		//}
	}
}

void CParticleEmitter::CopyMeTo(CParticleEmitter* newparticle)
{
	newparticle->name = this->name;
	newparticle->timer = this->timer;
	newparticle->imageId = this->imageId;
	newparticle->lifeTime = this->lifeTime;
	newparticle->numberOfParticles = this->numberOfParticles;
	newparticle->particleRate = this->particleRate;
	newparticle->originalBurstTime = this->originalBurstTime;
	newparticle->burstTimer = this->burstTimer;

	for(int i = 0; i < 4; ++i)
	{
		newparticle->rateColor[i] = this->rateColor[i];
	}

	newparticle->ratePosX = this->ratePosX;
	newparticle->ratePosY = this->ratePosY;
	newparticle->rateScale = this->rateScale;
	newparticle->rateVelX = this->rateVelX;
	newparticle->rateVelY = this->rateVelY;
	newparticle->startColor = this->startColor;
	newparticle->startPosX = this->startPosX;
	newparticle->startPosY = this->startPosY;
	newparticle->startScale = this->startScale;
	newparticle->startVelX = this->startVelX;
	newparticle->startVelY = this->startVelY;

	newparticle->emitterRectWidth = this->emitterRectWidth;
	newparticle->emitterRectHeight = this->emitterRectHeight;

	newparticle->sourceBlend = this->sourceBlend;
	newparticle->destinationBlend = this->destinationBlend;

	newparticle->isLooping = this->isLooping;

	for(int i(0); i < numberOfParticles; ++i)
	{
		Particle* add = new Particle(startPosX,startPosY,startVelY,startVelY,startScale,startColor,lifeTime);
		newparticle->deadParticles.push_back(add);
	}
}

void CParticleEmitter::Render()
{
	CSGD_Direct3D::GetInstance()->SpriteEnd();
	CSGD_Direct3D::GetInstance()->DeviceEnd();

	CSGD_Direct3D::GetInstance()->DeviceBegin();
	CSGD_Direct3D::GetInstance()->SpriteBegin();

	if(sourceBlend > 0)
		CSGD_Direct3D::GetInstance()->GetDirect3DDevice()->SetRenderState(D3DRS_SRCBLEND, sourceBlend );
	if(destinationBlend > 0)
		CSGD_Direct3D::GetInstance()->GetDirect3DDevice()->SetRenderState(D3DRS_DESTBLEND, destinationBlend );

	//if(!titleState)
	//	CCamera::GetInstance()->RenderCamera();

	for(unsigned i(0); i < aliveParticles.size(); ++i)
	{
		aliveParticles[i]->Render(imageId);
	}

	CSGD_Direct3D::GetInstance()->SpriteEnd();
	CSGD_Direct3D::GetInstance()->DeviceEnd();

	CSGD_Direct3D::GetInstance()->DeviceBegin();
	CSGD_Direct3D::GetInstance()->SpriteBegin();

	//if(!titleState)
	//	CCamera::GetInstance()->RenderCamera();
}

void CParticleEmitter::Load(const char* filename, int imageid)
{
	this->imageId = imageid;

	ifstream in;

	in.open(filename, std::ios_base::in | std::ios_base::binary);

	char throwaway[1];
	char buffer[32];

	int length = 0;
	in.read((char*)&length, sizeof(int));
	in.read(throwaway, 1);
	in.read(buffer, length);
	buffer[length] = 0;
	name = buffer;
	in.read((char*)&lifeTime, sizeof(float));
	in.read((char*)&numberOfParticles, sizeof(int));
	in.read((char*)&particleRate, sizeof(int));
	in.read((char*)&originalBurstTime, sizeof(float));
	burstTimer = originalBurstTime;
	in.read((char*)&ratePosX, sizeof(float));
	in.read((char*)&ratePosY, sizeof(float));
	in.read((char*)&rateScale, sizeof(float));
	in.read((char*)&rateVelX, sizeof(float));
	in.read((char*)&rateVelY, sizeof(float));
	in.read((char*)&startPosX, sizeof(float));
	in.read((char*)&startPosY, sizeof(float));

	float endPosX = 0.0f;
	in.read((char*)&endPosX, sizeof(float));
	float endPosY = 0.0f;
	in.read((char*)&endPosY, sizeof(float));

	in.read((char*)&startScale, sizeof(float));

	float endScale = 0.0f;
	in.read((char*)&endScale, sizeof(float));

	in.read((char*)&startVelX, sizeof(float));
	in.read((char*)&startVelY, sizeof(float));

	float endXVel = 0.0f;
	in.read((char*)&endXVel, sizeof(float));
	float endYVel = 0.0f;
	in.read((char*)&endYVel, sizeof(float));

	in.read((char*)&emitterRectWidth, sizeof(int));
	in.read((char*)&emitterRectHeight, sizeof(int));

	in.read((char*)&sourceBlend, sizeof(int));
	in.read((char*)&destinationBlend, sizeof(int));

	for(int i = 0; i < 4; ++i)
	{
		in.read((char *)startColorData+i, sizeof(char));
	}

	startColor = D3DCOLOR_ARGB(startColorData[0], startColorData[1], startColorData[2], startColorData[3]);

	unsigned char endColorA;
	in.read((char*)&endColorA, sizeof(char));
	unsigned char endColorR;
	in.read((char*)&endColorR, sizeof(char));
	unsigned char endColorG;
	in.read((char*)&endColorG, sizeof(char));
	unsigned char endColorB;
	in.read((char*)&endColorB, sizeof(char));

	for(int i = 0; i < 4; ++i)
	{
		in.read((char*)&rateColor[i], sizeof(float));
	}

	in.read((char*)&isLooping, sizeof(bool));
}

void CParticleEmitter::XMLLoad(const char* filename, int imageid)
{
	this->imageId = imageid;

	TiXmlDocument doc;

	if(doc.LoadFile(filename) == false)
		return;

	TiXmlElement* Root = doc.RootElement();

	if(Root == NULL)
		return;

	TiXmlElement* pEmitter = Root;

	//pEmitter->Attribute("name", &name);

	name = "blood";

	double temp;
	pEmitter->Attribute("particlelifetime", &temp);
	lifeTime = (float)temp;

	//temp.rCollision.top = atoi(CollisionFrameY->GetText());
	pEmitter->Attribute("numberofparticles", &numberOfParticles);
	pEmitter->Attribute("particlerate", &particleRate);

	pEmitter->Attribute("bursttimer", &temp);
	burstTimer = (float)temp;
	originalBurstTime = burstTimer;

	pEmitter->Attribute("xpositionrate", &temp);
	ratePosX = (float)temp;

	pEmitter->Attribute("ypositionrate", &temp);
	ratePosY = (float)temp;

	pEmitter->Attribute("scalerate", &temp);
	rateScale = (float)temp;

	pEmitter->Attribute("xvelocityrate", &temp);
	rateVelX = (float)temp;

	pEmitter->Attribute("yvelocityrate", &temp);
	rateVelY = (float)temp;

	pEmitter->Attribute("startxposition", &temp);
	startPosX = (float)temp;

	pEmitter->Attribute("startyposition", &temp);
	startPosY = (float)temp;


	double endPosX;
	double endPosY;
	pEmitter->Attribute("endxposition", &endPosX);
	pEmitter->Attribute("endyposition", &endPosY);

	pEmitter->Attribute("startscale", &temp);
	startScale = (float)temp;

	pEmitter->Attribute("startxvelocity", &temp);
	startVelX = (float)temp;

	pEmitter->Attribute("startyvelocity", &temp);
	startVelY = (float)temp;

	double endVelX;
	double endVelY;
	pEmitter->Attribute("endxvelocity", &endVelX);
	pEmitter->Attribute("endyvelocity", &endVelY);

	pEmitter->Attribute("emitterwidth", &emitterRectWidth);
	pEmitter->Attribute("emitterheight", &emitterRectHeight);

	pEmitter->Attribute("sourceblend", &sourceBlend);
	pEmitter->Attribute("destistionblend", &destinationBlend);

	int tempLooping;
	pEmitter->Attribute("islooping", &tempLooping);
	isLooping = (bool)tempLooping;

	
	for(int i = 0; i < 4; ++i)
	{
		pEmitter->Attribute("startcolorA", &temp);
		//in.read((char *)startColorData+i, sizeof(char));
	}

	startColor = D3DCOLOR_ARGB(175, 255, 0, 0);

	double endColorA;
	pEmitter->Attribute("endcolorA", &endColorA);

	double endColorR;
	pEmitter->Attribute("endcolorA", &endColorR);

	double endColorG;
	pEmitter->Attribute("endcolorA", &endColorG);

	double endColorB;
	pEmitter->Attribute("endcolorA", &endColorB);

}

void CParticleEmitter::UnLoad()
{
	for(unsigned i(0); i < deadParticles.size(); ++i)
	{
		delete deadParticles[i];
	}

	deadParticles.clear();

	for(unsigned i(0); i < aliveParticles.size(); ++i)
	{
		delete aliveParticles[i];
	}

	aliveParticles.clear();
}